#include "soft_timer.h"


typedef struct tagSoftTimerItem
{
	soft_timer_t				timeout;
	event_t							event;
}SoftTimerItem;

static SoftTimerItem soft_timer_table[SOFT_TIMER_MAX_COUNT] = {0};
static unsigned char soft_timer_step = 0;
static soft_timer_t	soft_timer_flag = 0;


void soft_timer_pulse()
{
	soft_timer_step++;
}


void soft_timer_manual_register(unsigned char id, event_t evt)
{
	if(id<SOFT_TIMER_MAX_COUNT)
	{
		soft_timer_table[id].timeout = 0;
		soft_timer_table[id].event = evt;
		soft_timer_flag &= ~(1<<id);
	}
}

unsigned char	soft_timer_auto_register(event_t evt, unsigned char auto_unregister)
{
	unsigned char i;
	
	for(i=0;i<SOFT_TIMER_MAX_COUNT;i++)
	{
		if(soft_timer_table[i].event == 0)
		{
			soft_timer_table[i].timeout = 0;
			soft_timer_table[i].event = evt;
			if(auto_unregister)
			{
				soft_timer_flag |= (1<<i);
			}
			else
			{
				soft_timer_flag &= ~(1<<i);
			}
			break;
		}
	}	
	return i;
}


void soft_timer_start(unsigned char id, soft_timer_t timeout)
{
	if(id<SOFT_TIMER_MAX_COUNT)
	{
		soft_timer_table[id].timeout = timeout;
	}
}

void soft_timer_stop(unsigned char id)
{
	if(id<SOFT_TIMER_MAX_COUNT)
	{
		soft_timer_table[id].timeout = 0;
	}
}

void soft_timer_clear()
{
	unsigned char i;
	
	for(i=0;i<SOFT_TIMER_MAX_COUNT;i++)
	{
		soft_timer_table[i].timeout = 0;
	}
}

void soft_timer_reset()
{
	unsigned char i;
	
	for(i=0;i<SOFT_TIMER_MAX_COUNT;i++)
	{
		soft_timer_table[i].timeout = 0;
		soft_timer_table[i].event = 0;
	}
	soft_timer_flag = 0;
}

void soft_timer_pull()
{
	unsigned char i;
	unsigned char step;
	
	if(soft_timer_step > 0)
	{
		step = soft_timer_step;
		soft_timer_step = 0;
		for(i=0;i<SOFT_TIMER_MAX_COUNT;i++)
		{
			if(soft_timer_table[i].timeout > 0)
			{
				if(soft_timer_table[i].timeout > step)
				{
					soft_timer_table[i].timeout -= step;
				}
				else
				{
					soft_timer_table[i].timeout = 0;
					event_post(soft_timer_table[i].event);
					
					if(soft_timer_flag & (1<<i))
					{
						soft_timer_table[i].event = 0;
					}			
				}
			}
		}
	}
}
